﻿using EndpointManagement;
using IM.Easy.Api.AccountManage;
using IM.Easy.Core.Attributes;
using IM.Easy.Core.Cache;
using IM.Easy.Core.Log;
using IM.Easy.Core.Result;
using IM.Easy.Core.Utils;
using IM.Easy.Entity.System;
using IM.Easy.SystemServices.IServices;
using IM.Easy.SystemServices.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing.Patterns;

namespace IM.Easy.Api.Filters
{
    public class PermissionFilter : ActionFilterAttribute, IActionFilter
    {
        private readonly AccountService _accountService;
        private readonly IHostEnvironment _hostEnvironment;

        public PermissionFilter(AccountService accountService, IHostEnvironment hostEnvironment)
        {
            _accountService = accountService;
            _hostEnvironment = hostEnvironment;
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var endpoint = context.HttpContext.GetEndpoint() as RouteEndpoint;
            if (endpoint != null)
            {
                var account = _accountService.GetCurrent();
                // 获取路由信息
                var routePattern = endpoint.RoutePattern.RawText;
                var api = GetApiDescrition(context);

                if (api == null)
                {
                    // 调试模式默认放行未注册接口
                    if (_hostEnvironment.IsDevelopment()) return;
                    else ExceptionUtils.ThrowBusinessException($"系统接口【{routePattern}】不存在");
                }


                if (!api.IsEnabled)
                    ExceptionUtils.ThrowBusinessException($"系统接口【{routePattern}】未启用");

                // 根据路径和方法从权限服务中检查用户权限
                if (api.AuthRequired && !account.HasPermission(api.PermissionKey))
                    ExceptionUtils.ThrowBusinessException($"权限不足：[{api.PermissionKey}]");



            }

        }


        private ApiPermissions? GetApiDescrition(ActionExecutingContext context)
        {
            var endpoint = (context.HttpContext.GetEndpoint() as RouteEndpoint)!;
            var routePattern = endpoint.RoutePattern.RawText;
            var method = context.HttpContext.Request.Method;
            var api = EndPointManager.Get($"{routePattern}:{method}");
            if (api == null)
            {
                var apiTag = endpoint.Metadata.GetMetadata<ApiAttribute>();
                if (apiTag != null)
                {
                    api = new ApiPermissions
                    {
                        AuthRequired = !apiTag.AllowAnonymous,
                        PermissionKey = apiTag.Perm,
                        IsEnabled = apiTag.Required,
                        HttpMethod = method,
                        Path = routePattern,
                        Name = apiTag?.Name
                    };
                }
            }
            return api;
        }
    }
}
